#include <windows.h>
#include <GL/gl.h>
#include "Camera.h"
#include "Game.h"

#include "Scene.h"
#include <gl/GLU.h>
#include <glut.h>

Camera::Camera( int width, int height, Game* game ) {
	m_game = game;
	m_interpolateCameraPos = true;
	m_screen = SDL_SetVideoMode(width, height, 0, SDL_INIT_AUDIO|SDL_OPENGL );

	float verh = width / (float)height;
	m_screensize = Position(200 * verh, 200);

	glMatrixMode( GL_PROJECTION );
		glOrtho( -m_screensize.x/2, m_screensize.x/2,  -m_screensize.y/2, m_screensize.y/2,  -10, 10 );
	glMatrixMode( GL_MODELVIEW );

	glDisable(GL_BLEND);
	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
Camera::~Camera() {
}


void Camera::render( float frametime )
{
	glClear( GL_COLOR_BUFFER_BIT );
	glLoadIdentity();

	glColor3f( 0, 0, 0.2 );
	glBegin(GL_QUADS);
		glVertex2f( -m_screensize.x/2, -m_screensize.y/2 );
		glVertex2f( m_screensize.x/2, -m_screensize.y/2 );

		glColor3f( 0.5, 0.5, 0.8 );
		glVertex2f( m_screensize.x/2, m_screensize.y/2 );
		glVertex2f( -m_screensize.x/2, m_screensize.y/2 );
	glEnd();

	// Update scroll position
	Player* player = m_game->getScene()->getPlayer();
	if(!player->isDead()){
		int diffX = abs(player->getPosition().x - m_cameraPos.x);
		int diffY = abs(player->getPosition().y - m_cameraPos.y);

		if( diffX > 50 || diffY > 50 )
		{
			m_interpolateCameraPos = true;
		}

		if( m_interpolateCameraPos )
		{
			m_cameraPos.x += ( player->getPosition().x - m_cameraPos.x) * frametime;
			m_cameraPos.y += ( player->getPosition().y - m_cameraPos.y) * frametime;

			if( diffX <= 5 && diffY <= 5 )
				m_interpolateCameraPos = false;
		}
	}

	// Draw world
	glPushMatrix();
	glTranslatef( -m_cameraPos.x, -m_cameraPos.y, 0.f );

	const std::vector<Entity*>& entities = m_game->getScene()->getEntities();
	std::vector<Entity*>::const_iterator it = entities.begin();
	for( ; it != entities.end(); it++ )
	{
		drawEntity( *it );
	}

	glPopMatrix();

	// Draw FPS
	glColor3f(0, 0, 1);
	char buf[128];
	sprintf( buf, "FPS: %ld", (unsigned long)(1.f/frametime) );
	drawText(Position((m_screensize.x / 2) - 30, (m_screensize.y / 2) - 10), buf);
}

void Camera::drawText(Position h, char *string)
{
	glColor3f(1,1,1);
	int len, i;
	glRasterPos2f(h.x, h.y);
	len = (int) strlen(string);
	for (i = 0; i < len; i++)
	{
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]);
	}
}

void Camera::drawEntity( Entity* ent )
{
	Texture& tex = ent->getTexture();
	const Color& col = ent->getColor();
	const Position& pos = ent->getPosition();

	glPushMatrix();
	glTranslatef( pos.x, pos.y, 0.f );

	glColor3f( col.red, col.green, col.blue );

	if( tex.isValid() )
	{
		tex.bind();

		glBegin(GL_QUADS);
		glTexCoord2f((tex.getMirror() ? 0 : 1 ),0.f); glVertex2f( 0.f, 0.f );
		glTexCoord2f((tex.getMirror() ? 0 : 1 ),1.f); glVertex2f( 0.f, ent->getHeight() );
		glTexCoord2f((tex.getMirror() ? 1 : 0 ),1.f); glVertex2f( ent->getWidth(), ent->getHeight()  );
		glTexCoord2f((tex.getMirror() ? 1 : 0 ),0.f); glVertex2f( ent->getWidth(), 0.f );
		glEnd();

		tex.unbind();
	}
	else
	{
		glBegin(GL_QUADS);
		glVertex2f( 0.f, 0.f );
		glVertex2f( 0.f, ent->getHeight() );
		glVertex2f( ent->getWidth(), ent->getHeight()  );
		glVertex2f( ent->getWidth(), 0.f );
		glEnd();
	}

	if( ent->hasBorder() )
	{
		glColor3f( 0, 0, 0 );
		glBegin(GL_LINE_LOOP);
		glVertex2f( 0, 0 );
		glVertex2f( 0, ent->getHeight() );
		glVertex2f( ent->getWidth(), ent->getHeight() );
		glVertex2f( ent->getWidth(), 0 );
		glEnd();
	}

	glPopMatrix();
}